package grammarLL1;

import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Production {
	private static Pattern productionPattern = Pattern.compile("^([a-zA-Z])\\s*([a-zA-Z]*)", Pattern.DOTALL);
	private NonTerminal n;
	private List<Symbol> symbols;
	
	public Production(String production) throws GrammarException {
		if (production == null || "".equals(production)) {
			throw new GrammarException("Production empty.");
		}
		
		Matcher m = productionPattern.matcher(production);
		
		if (m.find()) {
			String ntstr = m.group(1);
			
			// si ya existe ese no-terminal, traerlo y agregarle una produccion asociada
			if (Grammar.nonTerminals.containsKey(ntstr)) {
				NonTerminal nt = Grammar.nonTerminals.get(ntstr);
				this.n = nt;
				this.symbols = new LinkedList<Symbol>();
				buildRightPart(m.group(2)); // agregar listado de simbolos derechos
				nt.linkProduction(this);
			} else {
				// sino, crearlo.
				this.symbols = new LinkedList<Symbol>();
				this.n = new NonTerminal(ntstr);
				buildRightPart(m.group(2));
				n.linkProduction(this);
				Grammar.nonTerminals.put(ntstr, n);
			}
		}	
	}
	
	public List<Symbol> getSymbols() {
		return symbols;
	}
	
	public NonTerminal getN() {
		return n;
	}
	
	@Override
	public String toString() {
		String right = "";
		
		for (Symbol s : this.symbols) {
			right += s.toString();
		}
		return n.symbol + " -> " + right; 
	}

	private void buildRightPart(String rightPart) {
		char[] rightSymbols;
		String symbol;
		
		// ! es lambda
		if (rightPart != null && !rightPart.equals("")) {
			rightSymbols = rightPart.toCharArray();
		} else {
			rightSymbols = "!".toCharArray();
		}
		
		/*  Agrega al listado de simbolos derechos de esta produccion
		 * todos los simbolos que hay en rightSymbols, tomando cada
		 * caracter e instanciandolo con la clase concreta que corresponda
		 */
		for (char c : rightSymbols) {
			symbol = String.valueOf(c);
			this.symbols.add(Symbol.valueOf(symbol));
		}
	}
	
}
